package com.github.nuggets.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.nuggets.constant.DataBaseConstants;
import com.github.nuggets.model.entity.NuggetsAccountEntity;
import com.github.nuggets.model.entity.NuggetsFansEntity;
import com.github.nuggets.model.entity.NuggetsFoucEntity;
import com.github.nuggets.model.exception.BizException;
import com.github.nuggets.model.result.PageResult;
import com.github.nuggets.model.vo.NuggetsAccountDetailVO;
import com.github.nuggets.repository.AccountRepository;
import com.github.nuggets.repository.FansRepository;
import com.github.nuggets.repository.FoucRepository;
import com.github.nuggets.service.AccountRelationshipService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: wangsj
 * @date: 2022/3/18 4:08 下午
 */
@Service
public class AccountRelationshipServiceImpl implements AccountRelationshipService {

    @Autowired
    private AccountRepository accountRepository;
    @Autowired
    private FoucRepository foucRepository;
    @Autowired
    private FansRepository fansRepository;

    @Override
    public Boolean foucAccount(Long accountId, Long foucId) {

        NuggetsAccountEntity account = Optional.ofNullable(
                accountRepository.getById(accountId)
        ).orElseThrow(() -> new BizException("用户不存在"));

        NuggetsAccountEntity foucAccount = Optional.ofNullable(
                accountRepository.getById(foucId)
        ).orElseThrow(() -> new BizException("关注用户不存在"));

        //是否成功关注用户成功
        Boolean isFoucSuccess = false;


        Optional<NuggetsFoucEntity> foucRecord = foucRepository.findFoucRecord(accountId, foucId);

        if (foucRecord.isPresent()) {

            NuggetsFoucEntity record = foucRecord.get();
            if (record.getIsCancel() == DataBaseConstants.LOGIC_NOT_DELETE_VALUE) {
                throw new BizException("不能重复关注");
            }

            record.setIsCancel(DataBaseConstants.LOGIC_NOT_DELETE_VALUE);
            isFoucSuccess = foucRepository.updateById(record);

        } else {
            isFoucSuccess = foucRepository.addFoucRecord(accountId, foucId);

        }

        //被关注用户是否添加粉丝成功
        Boolean isAddFansSuccess = fansRepository.addFansRecord(foucId, accountId);


        //总数更新
        account.setFoucNum(account.getFoucNum() + 1);
        foucAccount.setFansNum(foucAccount.getFansNum() + 1);

        Boolean isUpdateAccountSuccess = accountRepository.updateById(account);
        Boolean isUpdateFoucAccountSuccess = accountRepository.updateById(foucAccount);

        return isFoucSuccess && isAddFansSuccess && isUpdateFoucAccountSuccess && isUpdateAccountSuccess;
    }

    @Override
    public Boolean cancelFoucAccount(Long accountId, Long foucId) {

        NuggetsAccountEntity account = Optional.ofNullable(
                accountRepository.getById(accountId)
        ).orElseThrow(() -> new BizException("用户不存在"));

        NuggetsAccountEntity foucAccount = Optional.ofNullable(
                accountRepository.getById(foucId)
        ).orElseThrow(() -> new BizException("取关用户不存在"));

        NuggetsFoucEntity foucRecord = foucRepository.findFoucRecord(accountId, foucId)
                .orElseThrow(() -> new BizException("未关注该用户，无法取关"));

        if (foucRecord.getIsCancel() == DataBaseConstants.LOGIC_DELETE_VALUE) {
            throw new BizException("未关注该用户，无法取关");
        }

        foucRecord.setIsCancel(DataBaseConstants.LOGIC_DELETE_VALUE);
        boolean isRemoveFoucRecord = foucRepository.updateById(foucRecord);

        boolean isRemoveFansRecord = true;
        Optional<NuggetsFansEntity> fansRecord = fansRepository.findFansRecord(foucId, accountId);
        if (fansRecord.isPresent()) {
            isRemoveFansRecord = fansRepository.removeById(fansRecord.get());
        }

        account.setFoucNum(account.getFoucNum() - 1);
        foucAccount.setFansNum(foucAccount.getFansNum() - 1);

        Boolean isUpdateAccountSuccess = accountRepository.updateById(account);
        Boolean isUpdateFoucAccountSuccess = accountRepository.updateById(foucAccount);

        return isRemoveFansRecord && isRemoveFoucRecord && isUpdateFoucAccountSuccess && isUpdateAccountSuccess;
    }

    @Override
    public PageResult<NuggetsAccountDetailVO> foucList(Long accountId, Integer pageIndex, Integer pageSize) {

        PageResult<Long> foucIds = foucRepository.pageFoucIds(accountId, pageIndex, pageSize);
        //根据id列表获取用户信息
        List<NuggetsAccountDetailVO> accountVOs = findAccountVOByIds(foucIds.getContent());
        PageResult<NuggetsAccountDetailVO> result = new PageResult<>();
        BeanUtil.copyProperties(foucIds, result);
        result.setContent(accountVOs);

        return result;
    }

    @Override
    public PageResult<NuggetsAccountDetailVO> fansList(Long accountId, Integer pageIndex, Integer pageSize) {

        //获取id列表
        PageResult<Long> fansIds = fansRepository.pageFansIds(accountId, pageIndex, pageSize);

        //根据id列表获取用户信息
        List<NuggetsAccountDetailVO> accountVOs = findAccountVOByIds(fansIds.getContent());
        PageResult<NuggetsAccountDetailVO> result = new PageResult<>();
        BeanUtil.copyProperties(fansIds, result);
        result.setContent(accountVOs);

        return result;
    }

    /**
     * 根据id列表查询Account且转为VO对象
     *
     * @param ids
     * @return
     */
    private List<NuggetsAccountDetailVO> findAccountVOByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }

        List<NuggetsAccountEntity> nuggetsAccountEntities = accountRepository.listByIds(ids);
        return nuggetsAccountEntities.stream().map(entity -> {
            NuggetsAccountDetailVO detailVO = new NuggetsAccountDetailVO();
            BeanUtil.copyProperties(entity, detailVO);
            return detailVO;
        }).collect(Collectors.toList());
    }


}
